/**
 * @description  : 数据库工具文件
 * @descriptionDetail : 数据库工具文件
 * @copyright    : 浙江烟草
 * @author       : mc
 * @create       : 2022-10-04 15:12:16
 */

// #ifdef H5
import Dexie from 'dexie';
// #endif
import deepClone from '../uview-ui/libs/function/deepClone.js';
/** 
 *数据库操作辅助类,定义对象、数据操作方法都在这里定义 
 */
const conf = {
  /* 数据库名*/
  tableName: 'monopoly',
  /* 数据库版本*/
  version: '1.0',
  /* 数据库描述*/
  dbDesc: 'monopoly',
  /* 数据库大小 kb*/
  dbSize: 500 * 1024,
}

const toModel = function(item) {
  let model = {};
  Object.keys(item).forEach(function(key) {
    let k = /_/.test(key) ? key.replace(/_(.)/g, function(m) {
      return m[1].toUpperCase();
    }) : key;

    model[k] = item[key];
  });
  return model;
};

const toModels = function(rows) {
  let models = [];
  for (let i = 0; i < rows.length; i++) {
    models.push(toModel(rows.item(i)));
  }
  return models;
};

// 更新字符处理
const splitu = function(obj,type) {
  let splitArr = [];
  for (let t in obj) {
    if(type){
      splitArr.push(t + ' in (' + obj[t] + ')');
    }else{
      splitArr.push(t + '="' + obj[t] + '"');
    }
  }
  return splitArr.join(',');
}

// 打开数据库
const openDB = function(success, fail) {
  // #ifdef  H5
  window.WEBSQL_DB = new Dexie(conf.tableName);
  success('数据库创建/打开成功!');
  // #endif

  // #ifdef APP-PLUS
  plus.sqlite.openDatabase({
    name: conf.tableName,
    path: '_doc/monopoly.db',
    success: function(e) {
      success('数据库创建/打开成功!');
    },
    fail: function(e) {
      fail("数据库创建/打开失败！");
    },
  });
  // #endif
}

/**
 * 批量创建表结构
 * @param {Array} sql
 * @param {Object} success
 * @param {Object} fail
 */
const createTableBath = function(sql, success, fail) {
  // #ifdef H5
  let objs = {};
  for (let i = 0; i < sql.length; i++){
    objs[sql[i].name] = sql[i].sql;
  }
  window.WEBSQL_DB.version(Number(conf.version).toFixed(0)).stores(objs);
  window.WEBSQL_DB.open().then(() => {
    console.log('数据库打开了');
    success(true);
  }).catch(function (e) {
    console.error("Open failed: " + e.stack);
    fail(false);
  });
  // #endif

  // #ifdef APP-PLUS
  plus.sqlite.executeSql({
    name: conf.tableName,
    sql: sql,
    success: function(e) {
      success(true);
    },
    fail: function(e) {
      fail(false);
    },
  });
  
  // #endif
}

/**
 * 插入数据
 * @param {Object} insertSql sql语句
 * @param {Object} values 值
 * @param {Object} createH5 indexdb的参数
 */
const insterData = function(insertSql, values, createH5) {
  return new Promise((resolve, reject) => {
    // #ifdef H5
    window.WEBSQL_DB.transaction('rw', window.WEBSQL_DB[createH5.name], () => {
      let objx = deepClone(createH5.sqlObj);
      for (let i = 0; i < createH5.insertSQL_H5.length; i++) {
        objx[createH5.insertSQL_H5[i]] = values[i];
      }
      return window.WEBSQL_DB[createH5.name].add(objx);
    }).then((key) => {
      resolve(key);
    }).catch(err => {
      reject();
    });
    // #endif
	
    // #ifdef APP-PLUS
    let sql = insertSql;
    for (let i = 0; i < values.length; i++) {
      sql = sql.replace('?', '"' + values[i] + '"');
    }
    plus.sqlite.executeSql({
      name: conf.tableName,
      sql: sql,
      success: function(e) {
        resolve();
      },
      fail: function(e) {
        reject();
      },
    });
    // #endif
  });
}

/**
 * 批量插入数据
 * var sqlStatements = [['INSERT INTO CODEDIRECTORY(baseCode,codeName) values(?,?)',[each.baseCode,each.codeName]],['INSERT INTO CODEDIRECTORY(baseCode,codeName) values(?,?)',[each.baseCode,each.codeName]]]
 * @param {Object} sqlStatements
 * @param {Object} createH5 数组 
 */
const insertDataBatch = function(sqlStatements,createH5) {
  return new Promise((resolve, reject) => {
    // #ifdef H5
    let arr = [];
    let names = [];
    for (let i = 0; i < createH5.length; i++) {
      let tmp = createH5[i];
      names.push(window.WEBSQL_DB[tmp.cho.name]);
      let objx = deepClone(tmp.cho.sqlObj);
      for (let j = 0; j < tmp.cho.insertSQL_H5.length; j++) {
        objx[tmp.cho.insertSQL_H5[j]] = tmp.val[j];
      }
      arr.push(objx);
    }
    window.WEBSQL_DB.transaction('rw', names, async () => {
      for (let i = 0; i < names.length; i++) {
        await names[i].bulkAdd(arr);
      }
    }).then(() => {
      resolve();
    }).catch(err => {
      console.error ("失败了");
      reject();
    });
    // #endif
	
    // #ifdef APP-PLUS
    let st = new Array();
    // 拼接sql数组
    for (let i = 0; i < sqlStatements.length; i++) {
      let item = sqlStatements[i];
      let sql = item[0];
      for (let j = 0; j < item[1].length; j++) {
        sql = sql.replace('?', '"' + item[1][j] + '"');
      }
      st.push(sql);
    }
    plus.sqlite.transaction({name: conf.tableName, operation: 'begin',});
    plus.sqlite.executeSql({
      name: conf.tableName,
      sql: st,
      success: function(e) {
        resolve();
      },
      fail: function(e) {
        console.log(e);
        reject();
      },
    });
    plus.sqlite.transaction({name: conf.tableName,operation: 'commit',});
    // #endif
  });
}
/**
 * 查询所有数据
 * @param {Object} selectSql sql语句
 * @param {Object} name  indexdb 用到
 */
const findAllData = function(selectSql, name) {
  return new Promise((resolve, reject) => {
    // #ifdef H5
    window.WEBSQL_DB[name].toArray().then(rs => {
      resolve(rs);
    }).catch(err => {
      resolve([]);
    });
    // #endif
    // #ifdef APP-PLUS
    plus.sqlite.selectSql({
      name: conf.tableName,
      sql: selectSql,
      success: function(data) {
        resolve(data);
      },
      fail: function(e) {
        resolve([]);
      },
    });
    // #endif
  });
}
/**
 * 根据条件查询
 * @param {Object} selectSql 查询语句 select * from DEMO where userCode=?
 * @param {Object} value 要查询的字段值 ["fengsx"]
 * @param {Object} createH5 
 * @param {Array} queryKeys 条件字段
 */
const findData = function(selectSql, value, createH5, queryKeys) {
  return new Promise((resolve, reject) => {
    // #ifdef H5
    if(value.length == 0){
      window.WEBSQL_DB[createH5.name].toArray().then(rs => {
        resolve(rs);
      }).catch(er => {
        resolve([]);
      });
    }else{
      let quD = {};
      for (let i = 0; i < queryKeys.length; i++) {
        quD[queryKeys[i]] = value[i];
      }
      window.WEBSQL_DB[createH5.name].where(quD).toArray().then(rs => {
        resolve(rs);
      }).catch(er => {
        resolve([]);
      });
    }
    // #endif
	
    // #ifdef APP-PLUS
    let sql = selectSql;
    // 拼接sql 
    for (let i = 0; i < value.length; i++) {
      sql = sql.replace('?', '"' + value[i] + '"');
    }
    plus.sqlite.selectSql({
      name: conf.tableName,
      sql: sql,
      success: function(data) {
        resolve(data);
      },
      fail: function(e) {
        resolve([]);
      },
    });
    // #endif
  });
}

/**
 * 更新数据
 * @param {Object} updateSql 更新sql语句示例：update DEMO set aaa=? where id=?
 * @param {Object} values 更新字段 ["a12","1"]
 * @param {Object} createH5 indexdb 数据
 * @param {Object} pt 修改内容
 */
const updateData = function(updateSql, values, createH5, pt) {
  return new Promise((resolve, reject) => {
    // #ifdef H5
    window.WEBSQL_DB[createH5.name].update(values[values.length - 1], pt).then(function (updated) {
      if (updated)
        resolve();
      else
        reject();
    });
    // #endif

    // #ifdef APP-PLUS
    let sql = updateSql;
    // 拼接sql 
    for (let i = 0; i < values.length; i++) {
      sql = sql.replace('?', '"' + values[i] + '"');
    }
    plus.sqlite.executeSql({
      name: conf.tableName,
      sql: sql,
      success: function(res) {
        resolve(true);
      },
      fail: function(e) {
        reject();
      },
    });
    // #endif
  });
};
/**
 * 更新数据
 * @param {Object} tableName 表名
 * @param {Object} filedValus 更新字段 示例： {"userCode":"111","aaa":"99999"}
 * @param {Object} where 条件  示例：{"id":"3"}
 * @param {Object} createH5 indexdb
 */
const updateDataBatch = function(tableName, filedValus, where, createH5) {
  return new Promise((resolve, reject) => {
    // #ifdef H5
    window.WEBSQL_DB[createH5.name].where(where).first().then(ob => {
      if(ob){
        for(let p in filedValus){
          ob[p] = filedValus[p];
        }
        window.WEBSQL_DB[createH5.name].put(ob).then(() => {
          resolve();
        }).catch(e => {
          reject();
        });
      }
    });
    // #endif
  
    // #ifdef APP-PLUS
    let filedVal = splitu(filedValus);
    let delWhere = splitu(where);
    let sql = 'update ' + tableName + ' set ' + filedVal + ' where ' + delWhere + '';
    plus.sqlite.executeSql({
      name: conf.tableName,
      sql: sql,
      success: function(res) {
        resolve();
      },
      fail: function(e) {
        reject();
      },
    });
    // #endif
  });
};
/**
 * 删除数据
 * @param {Object} tableName 表名
 * @param {Object} where where条件 示例 {"id":"2"}
 * @param {Object} createH5 indexdb
 * @param {String} type 删除类型 单条删除还是多条删除
 */
const deleteData = function(tableName, where, type) {
  return new Promise((resolve, reject) => {
    let delWhere = splitu(where,type);
    let sql = 'delete from ' + tableName + ' where ' + delWhere + ' ';
    // #ifdef H5
    window.WEBSQL_DB[tableName].where(where).delete().then(rs => {
      resolve();
    }).catch(er => {
      reject();
    });
    // #endif
 
    // #ifdef APP-PLUS
    plus.sqlite.executeSql({
      name: conf.tableName,
      sql: sql,
      success: function(res) {
        resolve();
      },
      fail: function(e) {
        reject();
      },
    });
    // #endif
  });
};

/**
 * 删除表数据
 * @param {Array} deleteSqls 删除语句
 * @param {Array} createH5S indexdb 理解这个方法是清楚所有数据
 */
const deleteDataBatch = function(deleteSqls, createH5S) {
  return new Promise((resolve, reject) => {
    // #ifdef H5
    let ars = [];
    for (let a in createH5S) {
      ars.push(window.WEBSQL_DB[createH5S[a].name]);
    }
    window.WEBSQL_DB.transaction('rw', ars, async () => {
      for (let i = 0; i < ars.length; i++) {
        await ars[i].clear();
      }
    }).then(() => {
      resolve();
    }).catch(er => {
      console.log('错误了=' + er);
      reject();
    });
    // #endif
    // #ifdef APP-PLUS
    plus.sqlite.executeSql({
      name: conf.tableName,
      sql: deleteSqls,
      success: function(res) {
        resolve();
      },
      fail: function(e) {
        reject();
      },
    });
    // #endif
  });
};

/**
 * 判断是否为空
 */
const isEmpty = function(value) {
  switch (typeof value) {
  case 'undefined':
    return true;
  case 'string':
    if (value.replace(/(^[ \t\n\r]*)|([ \t\n\r]*$)/g, '').length == 0) return true;
    break;
  case 'boolean':
    if (!value) return true;
    break;
  case 'number':
    if (0 === value || isNaN(value)) return true;
    break;
  case 'object':
    if (null === value || value.length === 0) return true;
    for (let i in value) {
      return false;
    }
    return true;
  }
  return false;
}

/**
 * 是否json字符串
 */
const jsonString = function(value) {
  if (typeof value == 'string') {
    try {
      let obj = JSON.parse(value);
      if (typeof obj == 'object' && obj) {
        return true;
      } else {
        return false;
      }
    } catch (e) {
      return false;
    }
  }
  return false;
}

export default {
  openDB,
  insterData,
  insertDataBatch,
  findAllData,
  findData,
  updateData,
  updateDataBatch,
  createTableBath,
  deleteData,
  deleteDataBatch,
  isEmpty,
  jsonString,
}
